﻿using System.Text;
namespace program
{
    class Functions
    {
        public static string? Encrypt(string s)
        {
            if (s == null) return null;
            byte[] b = Encoding.Default.GetBytes(s);
            byte[] t1 = new byte[(b.Length + 6) / 7 * 7];
            byte[] t2 = new byte[(b.Length + 6) / 7 * 8 + 5];

            b.CopyTo(t1, 0);

            for (int i = 0; i < 5; i++)
                t2[t2.Length - i - 1] = (byte)((b.Length >> (i * 7)) & 0x7F);
            for (int i = 0; i < t1.Length / 7; i++)
            {
                t2[i * 8 + 7] = (byte)(t1[i * 7 + 6] & 0x7F);
                int m = 0x3F;
                for (int j = 6; j >= 1; j--)
                {
                    t2[i * 8 + j] = (byte)(((t1[i * 7 + j - 1] & m) << (7 - j)) | (t1[i * 7 + j] >> (j + 1)));
                    m >>= 1;
                }

                t2[i * 8] = (byte)(t1[i * 7] >> 1);
            }

            string t3 = Encoding.Default.GetString(t2);
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < t3.Length; i++)
            {
                if (t3[i] == 0)
                    sb.Append("*?");
                else if (t3[i] == '*')
                    sb.Append("**");
                else
                    sb.Append(t3[i]);
            }
            return sb.ToString();
        }
        public static string? Decrypt(string s)
        {
            if (s == null)
                return null;
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < s.Length; i++)
            {
                if (s[i] == '*')
                {
                    i++;
                    if (s[i] == '?')
                        sb.Append('\0');
                    else
                        sb.Append('*');
                }
                else
                    sb.Append(s[i]);
            }

            byte[] t1 = Encoding.Default.GetBytes(sb.ToString());
            byte[] t2 = new byte[(t1.Length - 5) / 8 * 7];

            for (int i = 0; i < (t1.Length - 5) / 8; i++)
            {
                for (int j = 0; j <= 6; j++)
                {
                    t2[i * 7 + j] = (byte)((t1[i * 8 + j] << (j + 1)) | (t1[i * 8 + j + 1] >> (6 - j)));
                }
            }

            int len = (t1[t1.Length - 5] << 28) | (t1[t1.Length - 4] << 21) | (t1[t1.Length - 3] << 14) | (t1[t1.Length - 2] << 7) | t1[t1.Length - 1];
            return Encoding.Default.GetString(t2, 0, len);
        }
    }
    class Example
    {
        public static void Main(string[] args)
        {
            Console.Write("字符串加密前:");

            string s = Console.ReadLine() ?? "空";
            string? e = Functions.Encrypt(s);
            Console.WriteLine($"字符串加密后:{e}");

            string? d = Functions.Decrypt(e!);
            Console.WriteLine($"字符串解密后:{d}");
        }
    }
}